#include <iostream>
#include <memory>

class Person
{
public:
    Person(const std::string& strName, int nData)
        : _strName(strName),_nData(nData)
    {
        std::cout << "Person constructed: " << std::endl;
    }

    ~Person()
    {
        std::cout << "Person destroyed" << std::endl;
    }

    void show() const
    {
        std::cout << *this << std::endl;
    }

    friend std::ostream& operator << (std::ostream& os , const Person& ps)
    {
        os << ps._nData << " " << ps._strName ;
        return os;
    }
private:
    std::string _strName{};      // 名字
    int _nData{};                // 数据
};

int main()
{
    { // unique_ptr同一时间只能有一个unque_ptr拥有对象、禁止拷贝构造和拷贝赋值
        auto ptr1 = std::make_unique<Person>("Aiye" , 21); // 创建unique_ptr
        ptr1->show(); // 调用成员函数
        std::cout << *ptr1 << std::endl;

        auto ptr2 = std::move(ptr1); // 转移所有权
        if (!ptr1)
        {
            std::cout << "ptr1 is now nullptr" << std::endl;
        }

        ptr2.reset(new Person("Alice" , 21)); // 释放就对象管理新对象
        ptr2->show();

        auto rawPtr = ptr2.release(); // 释放所有权，返回原始指针
        rawPtr->show();
        delete rawPtr;
    }

    { // shared_ptr 共享同一个对象，采用引用技术机制，线程安全
        auto ptr1 = std::make_shared<Person>("Aiye" , 20);
        auto ptr2 = ptr1; // 拷贝构造-引用计数增加
        std::cout << "Count:" << ptr2.use_count() << std::endl;

        {
            auto ptr3 = ptr1 ;
            std::cout << "Count:" << ptr2.use_count() << std::endl;
        }
        std::cout << "Count:" << ptr2.use_count() << std::endl;

        ptr2.reset(); // 重置指针
        std::cout << "Count:" << ptr2.use_count() << std::endl;
    }

    return 0;
}